package servlet.song;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.AnonymousCOSCredentials;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.GeneratePresignedUrlRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import pojo.Songs;
import service.SongsService;
import service.impl.SongsServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.List;

@WebServlet("/song/uploadServlet")
public class UploadServlet extends HttpServlet {
    SongsService songsService = new SongsServiceImpl();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (!ServletFileUpload.isMultipartContent(request)) {
            // 给前端发送错误信息
            response.getWriter().write("{\"error\": \"上传的文件错误\"}");
            return;
        }
        InputStream ins = null;
        // 获取前端传来的字段信息
        try {
            // 创建一个 DiskFileItemFactory 实例，用于处理文件上传的相关操作
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 创建一个 ServletFileUpload 实例，使用上面的 factory
            ServletFileUpload upload = new ServletFileUpload(factory);
            String title = null;
            String description = null;
            String uploaderId = null;
            String categoryId = null;
            // 设置请求头编码为 UTF-8，确保能正确处理包含中文等特殊字符的请求
            upload.setHeaderEncoding("utf-8");
            // 解析 HTTP 请求，将其拆分成多个 FileItem，每个 FileItem 代表一个表单元素或文件上传项
            List<FileItem> items = upload.parseRequest(request);
            // 遍历解析得到的每个 FileItem
            for (FileItem item : items) {
                // 如果是普通表单元素（不是文件）
                if (item.isFormField()) {
                    // 普通表单字段
                    switch (item.getFieldName()) {
                        case "songName":
                            title = item.getString("UTF-8");
                            break;
                        case "description":
                            description = item.getString("UTF-8"); // 指定字符集编码方式，可以防止添加中文时乱码
                            break;
                        case "userId":
                            uploaderId = item.getString();
                            break;
                        case "categoryId":
                            categoryId = item.getString();
                            break;
                    }
                } else {
                    // 如果是文件上传项，获取文件的输入流
                    ins = item.getInputStream();
                    // 获取文件的原始名称
                    String filename = item.getName();
                    // 以下是腾讯云对象存储的操作
                    // 1. 初始化腾讯云 COS 的凭证，使用提供的 SecretId 和 SecretKey
                    COSCredentials cred = new BasicCOSCredentials("AKIDymV4S0ZTyLYZVHqrdhfZIuLl5IevkykM", "eMy1ucBZq1DNQLUUN8jEcufR4EE2f9h8");
                    // 2. 设置腾讯云 COS 的客户端配置，指定区域为北京
                    ClientConfig clientConfig = new ClientConfig(new Region("ap-beijing"));
                    // 3. 创建一个 COS 客户端
                    COSClient cosclient = new COSClient(cred, clientConfig);
                    // 存储桶名称
                    String bucketName = "ssss-999-1257238099";
                    // 存储在 COS 中的对象的键，使用文件的原始名称
                    String key = item.getName();
                    // 创建一个对象元数据对象
                    ObjectMetadata objectMetadata = new ObjectMetadata();
                    // 设置对象的大小为文件的大小
                    objectMetadata.setContentLength(item.getSize());
                    // 将文件上传到 COS 存储桶，使用文件输入流和对象元数据
                    PutObjectResult putObjectResult = cosclient.putObject(bucketName, key, ins, objectMetadata);
                    // 创建一个匿名的 COS 凭证
                    COSCredentials creded = new AnonymousCOSCredentials();
                    // 创建一个新的客户端配置，指定区域为北京
                    ClientConfig clientConfiged = new ClientConfig(new Region("ap-beijing"));
                    // 创建一个新的 COS 客户端
                    COSClient coscliented = new COSClient(creded, clientConfiged);
                    // 存储文件的名称
                    String name = filename;
                    // 创建一个生成预签名 URL 的请求，使用 GET 方法
                    GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, name, HttpMethodName.GET);
                    // 生成预签名 URL
                    URL url = coscliented.generatePresignedUrl(req);
                    // 去除文件名的后缀（假设是.xxx 后缀）
                    name = name.substring(0, name.length() - 4);
                    // 获取生成的预签名 URL 的字符串表示
                    String url1 = url.toString();
                    // 关闭 COS 客户端
                    coscliented.shutdown();
                    // 将文件信息添加到数据库中
//                    boolean s = add_music(name, url1, "");
                    Songs songs = new Songs(title, url1, description, Integer.parseInt(uploaderId), Integer.parseInt(categoryId));
                    boolean isAdded = songsService.insert(songs);
                    if (isAdded) {
                        // 插入成功，重定向到歌曲列表页面（或其他页面）
                        response.sendRedirect(request.getContextPath() +"/user/personalCenter.jsp");
                    } else {
                        // 插入失败，返回错误提示
                        response.getWriter().write("<script>alert('歌曲添加失败');</script>");
                    }
                }
            }
        } catch (FileUploadException e) {
            // 打印异常信息，便于调试
            e.printStackTrace();
        } finally {
            // 关闭文件输入流
            if (ins!= null) {
                try {
                    ins.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
